<template>
  <div>
    <VueDraggable v-model="structures" target=".el-table__body tbody" :animation="150" @end="onEnd">
      <el-table :data="structures" class="draggable" :lazy="false" max-height="700">
        <el-table-column prop="field" :label="$t('generate.schema.structure.field_name.name')" />
        <el-table-column prop="type" :label="$t('generate.schema.structure.type.name')">
          <template #default="scope">
            <el-tag type="success">{{ scope.row.type }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="nullable" :label="$t('generate.schema.structure.nullable')" width="90px">
          <template #default="scope">
            <el-tag v-if="scope.row.nullable">{{ $t('system.yes') }}</el-tag>
            <el-tag v-else type="info">{{ $t('system.no') }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="default" :label="$t('generate.schema.structure.default')" />
        <!--<el-table-column prop="comment" label="注释" />-->
        <el-table-column prop="id" :label="$t('generate.schema.structure.operate')" width="120px">
          <template #default="scope">
            <el-button type="primary" :icon="Edit" @click="updateField(scope.row.id)" size="small" />
            <el-button type="danger" :icon="Delete" @click="deleteField(scope.row.id)" size="small" />
          </template>
        </el-table-column>
      </el-table>
    </VueDraggable>
    <div class="flex justify-end mt-4">
      <el-button type="success" :icon="Plus" @click="addField">{{ $t('system.add') }}</el-button>
    </div>

    <div class="justify-between w-full pl-24 mx-auto mt-2 sm:w-96">
      <el-button class="mt-5" @click="emits('prev')">{{ $t('system.prev') }}</el-button>
      <el-button class="mt-5" type="primary" @click="next">{{ $t('system.confirm') }}</el-button>
    </div>

    <Dialog v-model="visible" :title="$t('system.add')" width="600px">
      <el-form :model="structure" status-icon label-width="120px" ref="form">
        <div class="grid justify-between grid-cols-2">
          <el-form-item
            :label="$t('generate.schema.structure.field_name.name')"
            prop="field"
            :rules="[
              {
                required: true,
                message: $t('generate.schema.structure.field_name.verify')
              }
            ]"
          >
            <el-input v-model="structure.field" />
          </el-form-item>
          <el-form-item
            class="w-full"
            :label="$t('generate.schema.structure.type.name')"
            prop="type"
            :rules="[
              {
                required: true,
                message: $t('generate.schema.structure.type.verify')
              }
            ]"
          >
            <el-select v-model="structure.type" :placeholder="$t('generate.schema.structure.type.placeholder')" filterable class="w-full">
              <el-option v-for="item in types" :key="item" :label="item" :value="item" />
            </el-select>
          </el-form-item>
        </div>
        <div class="grid grid-cols-2">
          <el-form-item :label="$t('generate.schema.structure.length')" prop="length">
            <el-input-number v-model="structure.length" :min="0" />
          </el-form-item>
          <el-form-item label="是否为空" prop="nullable">
            <el-switch v-model="structure.nullable" inline-prompt :active-text="$t('system.yes')" :inactive-text="$t('system.no')" />
          </el-form-item>
          <el-form-item :label="$t('generate.schema.structure.default')" prop="default" v-if="!structure.nullable">
            <el-input v-model="structure.default" />
          </el-form-item>
          <el-form-item :label="$t('generate.schema.structure.unique')" prop="unique">
            <el-switch v-model="structure.unique" inline-prompt :active-text="$t('system.yes')" :inactive-text="$t('system.no')" />
          </el-form-item>
        </div>
        <el-form-item :label="$t('generate.schema.structure.comment')" prop="comment">
          <el-input v-model="structure.comment" :rows="2" type="textarea" placeholder="表注释" />
        </el-form-item>
        <!-- 关联关系 -->
        <div class="flex justify-end">
          <el-button type="primary" @click="submitStructure(form)">{{ $t('system.confirm') }}</el-button>
        </div>
      </el-form>
    </Dialog>
  </div>
</template>
<script lang="ts" setup>
import { Ref, ref, watch } from 'vue'
import { useSchemaStore, Structure } from '../store'
import { Delete, Plus, Edit } from '@element-plus/icons-vue'
import type { FormInstance } from 'element-plus'
import Message from '@/support/message'
import http from '@/support/http'
import { Code } from '@/enum/app'
import { VueDraggable } from 'vue-draggable-plus'

const schemaStore = useSchemaStore()
const emits = defineEmits(['prev', 'next'])
const visible = ref(false)
// 初始化
const structures = ref(schemaStore.getStructures)

const structure: Ref<Structure> = ref(schemaStore.initStructure())
// 更新
const isUpdate = ref(false)
// structure
const addField = async () => {
  isUpdate.value = false
  await form.value?.clearValidate()
  visible.value = true
}

// 如果关闭了弹窗，重置表单的值
watch(
  () => visible.value,
  (val: boolean) => {
    if (!val) {
      structure.value = schemaStore.initStructure()
    }
  }
)

watch(
  () => schemaStore.getStructures,
  () => {
    structures.value = schemaStore.getStructures
  }
)

const updateField = (id: number) => {
  visible.value = true
  isUpdate.value = true
  structures.value.forEach(s => {
    if (s.id === id) {
      structure.value = s
    }
  })
  schemaStore.setStructures(structures.value)
}

const form = ref<FormInstance>()
const submitStructure = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {
      if (isExistField(structure.value.field, isUpdate.value ? structure.value.id : 0)) {
        Message.error(`${structure.value.field} 已存在，请修改字段名称`)
      } else {
        visible.value = !visible.value
        schemaStore.addStructure(structure.value)
        structure.value = schemaStore.initStructure()
      }
    }
  })
}

/**
 * 是否 field 存在
 *
 * @param field
 * @param id
 */
const isExistField = (field: string, id: number = 0) => {
  const fields: Array<string> = []
  structures.value.forEach((structure: Structure) => {
    if (id > 0) {
      if (structure.id !== id) {
        fields.push(structure.field)
      }
    } else {
      fields.push(structure.field)
    }
  })

  return fields.indexOf(field) !== -1
}
// 删除字段
const deleteField = (id: number) => {
  structures.value = structures.value.filter((s: Structure) => {
    return !(s.id === id)
  })
  schemaStore.setStructures(structures.value)
}

const next = () => {
  if (schemaStore.getStructures.length < 1) {
    Message.error('请先填写表结构数据')
  } else {
    http.post('schema', schemaStore.$state).then(r => {
      if (r.data.code === Code.SUCCESS) {
        Message.success('创建成功')
        schemaStore.finished()
      }
    })
  }
}

// 调整数据结构
const onEnd = () => {
  schemaStore.setStructures(structures.value)
}
const types: string[] = [
  'id',
  'smallIncrements',
  'mediumIncrements',
  'increments',
  'smallInteger',
  'integer',
  'bigIncrements',
  'bigInteger',
  'mediumInteger',
  'unsignedInteger',
  'unsignedMediumInteger',
  'unsignedSmallInteger',
  'unsignedTinyInteger',
  'string',
  'text',
  'binary',
  'boolean',
  'char',
  'dateTimeTz',
  'dateTime',
  'date',
  'decimal',
  'double',
  'float',
  'geometryCollection',
  'geometry',
  'ipAddress',
  'json',
  'jsonb',
  'lineString',
  'longText',
  'macAddress',
  'mediumText',
  'multiLineString',
  'multiPoint',
  'multiPolygon',
  'nullableMorphs',
  'nullableTimestamps',
  'nullableUuidMorphs',
  'point',
  'polygon',
  'timeTz',
  'time',
  'timestampTz',
  'timestamp',
  'timestampsTz',
  'timestamps',
  'tinyIncrements',
  'tinyInteger',
  'tinyText',
  'uuid',
  'year'
]
</script>
